package com.yue.encrypt;

import com.yue.encrypt.exception.CoderException;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * 功能描述: TODO <br/>
 * 创建时间: 2016/11/3<br/>
 *
 * @author QiuYang
 */
public abstract class Coder {
    /*
        org.apache.commons.codec 包， 实现了下面几种编码
        BASE64 严格地说，属于编码格式，而非加密算法
        MD5(Message Digest algorithm 5，信息摘要算法)
        SHA(Secure Hash Algorithm，安全散列算法)
        HMAC(Hash Message Authentication Code，散列消息鉴别码)
     */

    /* ---------algorithm------------ */
    public static final String KEY_DM5_ALGORITHM = "MD5";
    public static final String KEY_SHA1_ALGORITHM = "SHA1";
    public static final String KEY_SHA224_ALGORITHM = "SHA-224";
    public static final String KEY_SHA256_ALGORITHM = "SHA-256";
    public static final String KEY_SHA512_ALGORITHM = "SHA-512";

    public static final String KEY_MAC_ALGORITHM = "HmacMD5";

    /* ---------base64------------ */
    public static byte[] decryptBase64(String key){
        return Base64.getDecoder().decode(key);
    }

    public static String encryptBase64(byte[] key){
        return Base64.getEncoder().encodeToString(key);
    }

    public static boolean isBase64(String encryptKey){
        return false;
    }

    /* ---------MD5------------ */
    public static byte[] encryptMD5(byte[] data){
        return encrypt(data, KEY_DM5_ALGORITHM);
    }

    /* ---------SHA------------ */
    public static byte[] encryptSHA1(byte[] data) {
        return encrypt(data, KEY_SHA1_ALGORITHM);
    }

    public static byte[] encryptSHA224(byte[] data) {
        return encrypt(data, KEY_SHA224_ALGORITHM);
    }

    public static byte[] encryptSHA256(byte[] data) {
        return encrypt(data, KEY_SHA256_ALGORITHM);
    }

    public static byte[] encryptSHA512(byte[] data) {
        return encrypt(data, KEY_SHA512_ALGORITHM);
    }

    /* ---------common------------ */
    public static byte[] encrypt(byte[] data, String algorithm){
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance(algorithm);
            digest.update(data);
        } catch (NoSuchAlgorithmException e) {
            throw new CoderException(e);
        }
        return digest.digest();
    }

    /*------------HmacMD5---------------*/
    public static String initMacKey(){
        SecretKey secretKey = null;
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC_ALGORITHM);
            secretKey = keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new CoderException(e);
        }
        return Coder.encryptBase64(secretKey.getEncoded());
    }

    public static byte[] encryptHMAC(byte[] data, String key){
        SecretKey secretKey = new SecretKeySpec(Coder.decryptBase64(key), KEY_MAC_ALGORITHM);
        Mac mac = null;
        try {
            mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
        } catch (Exception e) {
            throw new CoderException(e);
        }

        return mac.doFinal(data);
    }


    public static void main(String[] args) {
        String str = "94f084c2a45f64c3004bb43919a17692";

        String encryptData = Coder.encryptBase64(str.getBytes());
        System.out.println(encryptData);

        System.out.println(Coder.encryptBase64(Coder.encryptMD5(str.getBytes())));

        System.out.println(Coder.encryptBase64(Coder.encryptSHA1(str.getBytes())));

        System.out.println(Coder.encryptBase64(Coder.encryptSHA224(str.getBytes())));

        System.out.println(Coder.encryptBase64(Coder.encryptSHA256(str.getBytes())));

        System.out.println(Coder.encryptBase64(Coder.encryptSHA512(str.getBytes())));

//        String str = "简单加密";

        String key = DESCoder.initMacKey();
        System.out.println(key);

        System.out.println(Coder.encryptBase64(DESCoder.encryptHMAC(str.getBytes(), key)));

        System.out.println(Coder.encryptBase64("94f084c2a45f64c3004bb43919a17692".getBytes()));

    }
}
